home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Sysmon120a.lha / sysmon / src / ShowSys.c < prev    next >
C/C++ Source or Header  |  2001-11-18  |  13KB  |  450 lines

  1. /*
  2. **    $RCSfile: ShowSys.c,v $
  3. **    $Filename: ShowSys.c $
  4. **    $Revision: 1.7 $
  5. **    $Date: 2001/04/28 16:28:28 $
  6. **
  7. **    sysmon.library Task display command ShowSys (version 1.8)
  8. **    
  9. **    (C) Copyright 1995-2001 by Etienne Vogt
  10. **    64/32 Division algorithm kindly provided by Thomas Richter
  11. */
  12.  
  13. #include <exec/alerts.h>
  14. #include <exec/memory.h>
  15. #include <exec/execbase.h>
  16. #include <dos/dosextens.h>
  17. #include <dos/var.h>
  18. #include <dos/datetime.h>
  19. #include <workbench/startup.h>
  20. #include <devices/timer.h>
  21. #define __USE_SYSBASE
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/utility.h>
  25. #include <proto/timer.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include "sysmon.h"
  30. #include "sysmon_protos.h"
  31. #include "sysmon_pragmas.h"
  32.  
  33. #define TIBUFMAX    30
  34. #define TNAMEMAX    31
  35. #define NT_CLI    NT_USER
  36.  
  37. struct tiBuffer
  38. {    struct TaskInfo tib_tinfo;
  39.     char    tib_name[TNAMEMAX];
  40.     UBYTE    tib_type;
  41.     LONG    tib_clinum;
  42.     ULONG    tib_stacksize;
  43.     ULONG    tib_sigalloc;
  44.     ULONG    tib_sigwait;
  45.     ULONG    tib_sigrecvd;
  46.     ULONG    tib_sigexcept;
  47.     BYTE    tib_pri;
  48.     UBYTE    tib_flags;
  49.     UBYTE    tib_state;
  50. };
  51.     
  52. struct tiBufArray
  53. {    struct tiBufArray *tba_Link;
  54.     struct tiBuffer tba_bufs[TIBUFMAX];
  55. };
  56.  
  57. struct ExecBase *SysBase;
  58. struct DosLibrary *DOSBase;
  59. struct SysmonBase *SysmonBase;
  60. struct Device *TimerBase;
  61. struct timerequest myTimeReq;
  62. static struct WBStartup *wbmsg;
  63. static struct RDArgs *myrda;
  64.  
  65. ULONG __saveds  main(void);
  66. static void cleanexit(ULONG rc);
  67. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate);
  68. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate);
  69. static char *taskstate(UBYTE state, ULONG sigwait);
  70. static char *taskflags(UBYTE flags, UBYTE moreflags);
  71. static char *tasktype(UBYTE type, LONG clinum);
  72. static char *bstr2c(BSTR bstring);
  73. static char *cpustr(UWORD cpuflags);
  74. static char *filterctrl(char *string);
  75. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator);
  76. APTR SPrintf(STRPTR buffer, STRPTR format, ...);
  77. void freetibufs(struct tiBufArray *tibufs);
  78.  
  79. static UBYTE version[] = "$VER: ShowSys 1.8 (18.11.2001)";
  80. static UBYTE template[] = "FULL/S";
  81.  
  82. #define    OPT_FULL    0
  83. #define OPTMAX        1
  84.  
  85. ULONG __saveds main(void)    /* No startup code */
  86. {
  87.   struct Process *myproc;
  88.   ULONG EClockRate;
  89.   struct tiBufArray *tibufs;
  90.   LONG opts[OPTMAX];
  91.  
  92.   SysBase = *(struct ExecBase **)4;
  93.   DOSBase = NULL;
  94.   SysmonBase = NULL;
  95.   TimerBase = NULL;
  96.   wbmsg = NULL;
  97.   myrda = NULL;
  98.  
  99.   myproc = (struct Process *)FindTask(NULL);
  100.   if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
  101.   { Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
  102.     return 100;
  103.   }
  104.  
  105.   if (!(myproc->pr_CLI))        /* If started from WB, exit cleanly */
  106.   { WaitPort(&(myproc->pr_MsgPort));
  107.     wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
  108.     cleanexit(20);
  109.   }
  110.  
  111.   if ((SysmonBase = (struct SysmonBase *)OpenLibrary("sysmon.library",1)) == NULL)
  112.   { if (DOSBase->dl_lib.lib_Version >= 36) PutStr("ShowSys : Couldn't open sysmon.library V1+.\n");
  113.     cleanexit(20);
  114.   }
  115.  
  116.   if (OpenDevice(TIMERNAME, UNIT_ECLOCK, (struct IORequest *)&myTimeReq, 0L))
  117.   { Alert(AT_Recovery|AG_OpenDev|AO_TimerDev);
  118.     cleanexit(100);
  119.   }
  120.   else
  121.   { char Workbench[8], NodeName[16];
  122.     struct EClockVal UpTime;
  123.     struct DateTime SysTime;
  124.     UBYTE strDate[LEN_DATSTRING], strTime[LEN_DATSTRING];
  125.  
  126.     memset((char *)opts, 0, sizeof(opts));
  127.     if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
  128.     { PrintFault(IoErr(),"ShowSys");
  129.       cleanexit(20);
  130.     }
  131.  
  132.     TimerBase = myTimeReq.tr_node.io_Device;
  133.     EClockRate = ReadEClock(&UpTime);
  134.     if (GetVar("Workbench", Workbench, sizeof(Workbench) - 1, GVF_GLOBAL_ONLY) > 0)
  135.       Printf("AmigaOS %s", Workbench);
  136.     else PutStr("AmigaOS ?????");
  137.     if (GetVar("HostName", NodeName, sizeof(NodeName) - 1, GVF_GLOBAL_ONLY) > 0)
  138.       Printf(" at %s", NodeName);
  139.     else PutStr(" at ????? ");
  140.     DateStamp(&SysTime.dat_Stamp);
  141.     SysTime.dat_Format = FORMAT_DOS;
  142.     SysTime.dat_Flags = 0;
  143.     SysTime.dat_StrDay = NULL;
  144.     SysTime.dat_StrDate = strDate;
  145.     SysTime.dat_StrTime = strTime;
  146.     if (DateToStr(&SysTime)) Printf("   %s %s", SysTime.dat_StrDate, SysTime.dat_StrTime);
  147.     else Printf("                    ");
  148.     Printf("   UpTime :%s\n", uptimestr(&UpTime, EClockRate));
  149.   }
  150.   
  151.   Printf("Address  Name                           State  Pri   CPU [%.5s]    Type\n",cpustr(SysBase->AttnFlags));
  152.   if (opts[OPT_FULL]) Printf(">  Stack  SigAlloc SigWait  SigRecvd SigExcpt  Flags      Dispatch\n");
  153.  
  154.   if ((tibufs = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  155.   { PutStr("ShowSys : No memory for TaskInfo buffers.\n");
  156.     cleanexit(20);
  157.   }
  158.   else
  159.   { struct TaskInfo *tinfo = NULL;
  160.     struct tiBufArray *tba = tibufs;
  161.     struct tiBuffer *buf;
  162.     int j, i = 0, numtask = 0;
  163.  
  164.     smLockTaskTable(LTTF_READ);
  165.     while (tinfo = smNextTaskInfo(tinfo))
  166.     { struct Task *task;
  167.       struct CommandLineInterface *cli;
  168.       char *comname;
  169.       int n;
  170.  
  171.       numtask++;
  172.       buf = &tba->tba_bufs[i];
  173.       memcpy(buf, tinfo, sizeof(struct TaskInfo));
  174.       task = tinfo->ti_Task;
  175.       if (task->tc_Node.ln_Name) strcpy(buf->tib_name, filterctrl(task->tc_Node.ln_Name));
  176.       else strcpy(buf->tib_name, "<< No Name >>");
  177.       buf->tib_flags = task->tc_Flags;
  178.       buf->tib_state = task->tc_State;
  179.       buf->tib_sigalloc = task->tc_SigAlloc;
  180.       buf->tib_sigwait = task->tc_SigWait;
  181.       buf->tib_sigrecvd = task->tc_SigRecvd;
  182.       buf->tib_sigexcept = task->tc_SigExcept;
  183.       if (buf->tib_state == TS_WAIT && task->tc_SigWait == 0) buf->tib_state = TS_STOP;
  184.       buf->tib_pri = task->tc_Node.ln_Pri;
  185.       buf->tib_type = task->tc_Node.ln_Type;
  186.       if (buf->tib_type == NT_PROCESS && (cli = BADDR(((struct Process *)task)->pr_CLI)))
  187.       { buf->tib_clinum = ((struct Process *)task)->pr_TaskNum;
  188.     buf->tib_type = NT_CLI;
  189.     buf->tib_stacksize = cli->cli_DefaultStack * sizeof(ULONG);
  190.     if (cli->cli_Module && (comname = bstr2c(cli->cli_CommandName)) && (n = strlen(buf->tib_name)) < TNAMEMAX - 4)
  191.     { comname = filterctrl(FilePart(comname));
  192.       strcat(buf->tib_name, " (");
  193.       strncat(buf->tib_name, comname, TNAMEMAX - n - 4);
  194.       strcat(buf->tib_name, ")");
  195.     }
  196.       }
  197.       else if (buf->tib_type == NT_PROCESS) buf->tib_stacksize = ((struct Process *)task)->pr_StackSize;
  198.       else buf->tib_stacksize = (ULONG)task->tc_SPUpper - (ULONG)task->tc_SPLower;
  199.  
  200.       if (++i == TIBUFMAX)
  201.       { struct tiBufArray *tba1;
  202.  
  203.     if (tba1 = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR))
  204.     { tba->tba_Link = tba1;
  205.       tba = tba1;
  206.       i = 0;
  207.     }
  208.     else
  209.     { smUnLockTaskTable(LTTF_READ);
  210.       freetibufs(tibufs);
  211.       Printf("ShowSys : No memory for TaskInfo buffers.\n");
  212.       cleanexit(20);
  213.     }
  214.       }
  215.     }
  216.     smUnLockTaskTable(LTTF_READ);
  217.  
  218.     for (j = 0, tba = tibufs, i = 0 ; j < numtask ; j++)
  219.     { buf = &tba->tba_bufs[i];
  220.       Printf("%08lx %-30.30s %-5s %4ld %16s %-8s\n", buf->tib_tinfo.ti_Task,
  221.         buf->tib_name, taskstate(buf->tib_state, buf->tib_sigwait), buf->tib_pri,
  222.         cputimestr(&buf->tib_tinfo.ti_CPUTime, EClockRate),
  223.         tasktype(buf->tib_type, buf->tib_clinum));
  224.       if (opts[OPT_FULL]) Printf(">%7lu  %08lx %08lx %08lx %08lx  %8s %10lu\n", buf->tib_stacksize,
  225.         buf->tib_sigalloc, buf->tib_sigwait, buf->tib_sigrecvd, buf->tib_sigexcept,
  226.         taskflags(buf->tib_flags, buf->tib_tinfo.ti_Flags), buf->tib_tinfo.ti_DispCount);
  227.  
  228.       if (CheckSignal(SIGBREAKF_CTRL_C))
  229.       { PutStr("*** BREAK ***\n");
  230.     break;
  231.       }
  232.  
  233.       if (++i == TIBUFMAX) 
  234.       { tba = tba->tba_Link;
  235.     i = 0;
  236.       }
  237.     }
  238.     freetibufs(tibufs);
  239.   }
  240.   cleanexit(0);
  241. }
  242.  
  243. static void cleanexit(ULONG rc)
  244. {
  245.   if (TimerBase) CloseDevice((struct IORequest *)&myTimeReq);
  246.   if (SysmonBase) CloseLibrary((struct Library *)SysmonBase);
  247.   if (myrda) FreeArgs(myrda);
  248.   if (wbmsg)
  249.   { Forbid();
  250.     ReplyMsg((struct Message *)wbmsg);
  251.   }
  252.   if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  253.   Exit(rc);
  254. }
  255.  
  256. static char *uptimestr(struct EClockVal *clockval, ULONG clockrate)
  257. { static char buffer[16];
  258.   ULONG seconds;
  259.   UWORD updays, uphours, upminutes, upseconds;
  260.  
  261.   seconds = EClockDivide(clockval, clockrate);
  262.   updays = seconds / (24*60*60);
  263.   seconds %= 24*60*60;
  264.   uphours = seconds / (60*60);
  265.   seconds %= 60*60;
  266.   upminutes = seconds / 60;
  267.   upseconds = seconds % 60;
  268.   SPrintf(buffer, "%4lu-%02lu:%02lu:%02lu", updays, uphours, upminutes, upseconds);
  269.   return buffer; 
  270. }
  271.  
  272. static char *cputimestr(struct EClockVal *clockval, ULONG clockrate)
  273. { static char buffer[18];
  274.   ULONG seconds;
  275.   UWORD cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis;
  276.  
  277.   seconds = EClockDivide(clockval, clockrate);
  278.   cpudays = seconds / (24*60*60);
  279.   seconds %= 24*60*60;
  280.   cpuhours = seconds / (60*60);
  281.   seconds %= 60*60;
  282.   cpuminutes = seconds / 60;
  283.   cpuseconds = seconds % 60;
  284.   cpumillis = clockval->ev_lo / (clockrate / 1000);
  285.   if (cpumillis == 1000) cpumillis--;
  286.   SPrintf(buffer, "%3lu-%02lu:%02lu:%02lu.%03lu", cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis);
  287.   return buffer;
  288. }
  289.  
  290. static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator)
  291. { int bits;
  292.   ULONG d1,d2,d3;
  293.  
  294.   d1 = 0x0;
  295.   d2 = numerator->ev_hi;
  296.   d3 = numerator->ev_lo;
  297.  
  298.   for (bits = 0; bits < 64; bits++)
  299.   { /* now left-shift d1,d2,d3 */
  300.     d1 <<= 1;
  301.     if (d2 & 0x80000000) d1 |= 0x1;
  302.     d2 <<= 1;
  303.     if (d3 & 0x80000000) d2 |= 0x1;
  304.     d3 <<= 1;
  305.  
  306.     if (d1 >= denominator) 
  307.     { d1 -= denominator;
  308.       d3 |= 0x1;
  309.     }
  310.   }
  311.  
  312.   /* fill in the remainder */
  313.   numerator->ev_lo = d1;
  314.  
  315.   /* return the quotient, or the low part of it, at least */
  316.   return d3;
  317. }
  318.  
  319. static char *taskflags(UBYTE flags, UBYTE moreflags)
  320. { static char buffer[9];
  321.  
  322.   buffer[0] = (flags & TF_LAUNCH) ? 'L' : '-';
  323.   buffer[1] = (flags & TF_SWITCH) ? 'S' : '-';
  324.   buffer[2] = (flags & TF_EXCEPT) ? 'E' : '-';
  325.   buffer[3] = (flags & TF_STACKCHK) ? 'C' : '-';
  326.   buffer[4] = (flags & TF_ETASK) ? 'X' : '-';
  327.   buffer[5] = (flags & TF_PROCTIME) ? 'P' : '-';
  328.   buffer[6] = (moreflags & TIF_INEXCEPT) ? 'I' : '-';
  329.   buffer[7] = (moreflags & TIF_WAKEUP) ? 'W' : '-';
  330.   buffer[8] = '\0';
  331.   return buffer;
  332. }
  333.  
  334. static char *taskstate(UBYTE state, ULONG sigwait)
  335. {
  336.   switch(state)
  337.   { case TS_INVALID:
  338.       return "INVLD";
  339.     case TS_ADDED:
  340.       return "ADDED";
  341.     case TS_RUN:
  342.       return "RUN";
  343.     case TS_READY:
  344.       return "READY";
  345.     case TS_WAIT:
  346.       if (sigwait == 0) return "STOP";
  347.       else if (sigwait == SIGF_ABORT) return "SWABO";
  348.       else if (sigwait == SIGF_CHILD) return "SWCHI";
  349.       else if (sigwait == SIGF_SINGLE) return "SWSIN";
  350.       else if (sigwait == SIGF_INTUITION) return "SWINT";
  351.       else if (sigwait == SIGF_NET) return "SWNET";
  352.       else if (sigwait == SIGF_DOS) return "SWDOS";
  353.       else if (sigwait == SIGBREAKF_CTRL_C) return "SWBRC";
  354.       else if (sigwait == SIGBREAKF_CTRL_D) return "SWBRD";
  355.       else if (sigwait == SIGBREAKF_CTRL_E) return "SWBRE";
  356.       else if (sigwait == SIGBREAKF_CTRL_F) return "SWBRF";
  357.       else return "WAIT";
  358.     case TS_EXCEPT:
  359.       return "EXCPT";
  360.     case TS_REMOVED:
  361.       return "REMVD";
  362.     case TS_STOP:
  363.       return "STOP";
  364.     case TS_FROZEN:
  365.       return "FROZN";
  366.     case TS_HIBERNATE:
  367.       return "HIBER";
  368.     case TS_PAGEFLTWAIT:
  369.       return "PGFWT";
  370.     case TS_WAITAND:
  371.       return "WAITA";
  372.     case TS_TRAP:
  373.       return "TRAP";
  374.     case TS_FREEWAIT:
  375.       return "FREWT";
  376.  
  377.     default:
  378.       return "?????";
  379.   }
  380. }
  381.  
  382. static char *tasktype(UBYTE type, LONG clinum)
  383. { static char buffer[10];
  384.  
  385.   switch(type)
  386.   { case NT_TASK:
  387.       SPrintf(buffer,"Task");
  388.       break;
  389.     case NT_PROCESS:
  390.       SPrintf(buffer,"Process");
  391.       break;
  392.     case NT_CLI:
  393.       SPrintf(buffer,"Cli %-4ld",clinum);
  394.       break;
  395.     default:
  396.       SPrintf(buffer,"???");
  397.       break;
  398.   }
  399.   return buffer;
  400. }
  401.  
  402. #define    AFB_68060    7
  403. #define AFF_68060    (1L<<7)
  404.  
  405. static char *cpustr(UWORD cpuflags)
  406. {
  407.   if (cpuflags & AFF_68060) return "68060";
  408.   else if (cpuflags & AFF_68040) return "68040";
  409.   else if (cpuflags & AFF_68030) return "68030";
  410.   else if (cpuflags & AFF_68020) return "68020";
  411.   else if (cpuflags & AFF_68010) return "68010";
  412.   else return "68000";
  413. }
  414.  
  415. static char *bstr2c(BSTR bstring)
  416. { static char buffer[256];
  417.   char *ptr;
  418.   int n;
  419.  
  420.   if ((ptr = BADDR(bstring)) == NULL || (n = *ptr++) == 0) return NULL;
  421.   strncpy(buffer, ptr, n);
  422.   buffer[n] = 0;
  423.   return buffer;
  424. }
  425.  
  426. static char *filterctrl(char *string)
  427. { static char buffer[TNAMEMAX];
  428.   int i;
  429.  
  430.   for (i = 0 ; *string && i < TNAMEMAX - 1 ; i++, string++)
  431.   { if ((*string & 0x7f) < ' ') buffer[i] = '.';
  432.     else buffer[i] = *string;
  433.   }
  434.   buffer[i] = 0;
  435.   return buffer;
  436. }
  437.  
  438. APTR SPrintf(STRPTR buffer, STRPTR format, ...)
  439. { return smVSPrintf(buffer, format, &format + 1);
  440. }
  441.  
  442. void freetibufs(struct tiBufArray *tibufs)
  443. { struct tiBufArray *nexttba;
  444.  
  445.   do
  446.   { nexttba = tibufs->tba_Link;
  447.     FreeVec(tibufs);
  448.   } while (tibufs = nexttba);
  449. }
  450.